'''Reproduces the demo from PyOpenCL (examples/demo.py, also at
http://documen.tician.de/pyopencl/) using the simple wrapper API + In/Out.'''

import numpy
import numpy.linalg as la
from ahh.util.opencl import SimpleDeviceContext

## Create an OpenCL context
ctx = SimpleDeviceContext.create_somehow()

## Initialize memory
a = numpy.random.rand(50000).astype(numpy.float32)
b = numpy.random.rand(50000).astype(numpy.float32)
c = numpy.empty_like(a)

## Compile a program
prg = ctx.compile("""
    __kernel void sum(__global const float *a,
                      __global const float *b,
                      __global float *c)
    {
      int gid = get_global_id(0);
      c[gid] = a[gid] + b[gid];
    }
""")

## Run a program (implicitly copying memory in or out, see also InOut)
prg.sum(a.shape, ctx.In(a), ctx.In(b), ctx.Out(c))

## Verify the results
print la.norm(c - (a+b))
